package com.zhang;


import com.nimbusds.jose.JWSAlgorithm;
import com.zhang.Token.JwtToken;
import com.zhang.checker.IJwtService;
import com.zhang.checker.Resolver;
import com.zhang.checker.impl.JwtService;
import com.zhang.dataSource.ApiDBservice;
import com.zhang.dataSource.IDBServcice;
import com.zhang.filter.ApiFilter;
import com.zhang.filter.JwtFilter;
import com.zhang.realm.DBRealm;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SubjectDAO;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.crypto.KeyGenerator;
import javax.servlet.Filter;
import java.security.NoSuchAlgorithmException;


@Configuration
public class ShiroConfig {


    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

        chainDefinition.addPathDefinition("/api/**", "corsFilter,jwtFilter,apiFilter");
        chainDefinition.addPathDefinition("/**", "corsFilter");
        return chainDefinition;
    }


    /**
     * 解决跨域问题的Filter
     *
     * @return
     */
    @Bean(name = "corsFilter")
    public Filter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
        corsConfiguration.addAllowedHeader("*"); // 2允许任何头
        corsConfiguration.addAllowedMethod("*"); // 3允许任何方法（post、get等）

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration); // 4
        return new CorsFilter(source);
    }

    @Bean(name = "apiFilter")
    public ApiFilter apiFilter(IDBServcice dbServcice, ApiDBservice apiDBservice){
        return new ApiFilter(dbServcice,apiDBservice);
    }


    @Bean(name = "jwtFilter")
    public JwtFilter jwtFilter(){
        return new JwtFilter();
    }

    @Bean
    @ConditionalOnMissingBean
    public Realm DBRealm(Resolver jwtService){
        //设置APP层的数据源
        DBRealm realm = new DBRealm(jwtService);
        //设置支持的Token
        realm.setAuthenticationTokenClass(JwtToken.class);
        return realm;
    }

    /**
     * @return jwtService 提供jwt创建，解析操作
     */
    @Bean
    public IJwtService jwtService(){
        try {
            return new JwtService(new String(KeyGenerator.getInstance("HmacSHA256").generateKey().getEncoded()),
                    JWSAlgorithm.HS256.getName());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 无状态服务，shiro不保存session信息
     */
    @Bean
    public SubjectDAO subjectDAO() {
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        subjectDAO.setSessionStorageEvaluator((s) -> false);
        return subjectDAO;
    }
}
